"""
配置加载器
统一解析 plugin.yml 清单文件
"""

import os
import yaml
from typing import Any, Dict, List, Optional
from .exc import PluginConfigError


class PluginConfig:
    """插件配置数据类"""
    
    def __init__(self, config_dict: Dict[str, Any]) -> None:
        self.name: str = config_dict.get('name', '')
        self.version: str = config_dict.get('version', '1.0.0')
        self.author: str = config_dict.get('author', 'Unknown')
        self.description: str = config_dict.get('description', '')
        self.entry_class: str = config_dict.get('entry_class', '')
        self.dependencies: List[str] = config_dict.get('dependencies', [])
        self.config: Dict[str, Any] = config_dict.get('config', {})
        self.enabled: bool = config_dict.get('enabled', True)
        self.priority: int = config_dict.get('priority', 100)
        
        # 验证必需字段
        if not self.name:
            raise PluginConfigError("Plugin name is required")
        if not self.entry_class:
            raise PluginConfigError("Entry class is required")
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'name': self.name,
            'version': self.version,
            'author': self.author,
            'description': self.description,
            'entry_class': self.entry_class,
            'dependencies': self.dependencies,
            'config': self.config,
            'enabled': self.enabled,
            'priority': self.priority,
        }


class ConfigLoader:
    """
    配置加载器
    
    负责解析插件配置文件（plugin.yml）
    支持的字段：
    - name: 插件名称（必需）
    - version: 版本号
    - author: 作者
    - description: 描述
    - entry_class: 入口类名（必需）
    - dependencies: 依赖列表
    - config: 默认配置
    - enabled: 是否启用
    - priority: 加载优先级
    """
    
    @staticmethod
    def load_from_file(file_path: str) -> PluginConfig:
        """
        从YAML文件加载配置
        
        Args:
            file_path: 配置文件路径
            
        Returns:
            PluginConfig对象
            
        Raises:
            PluginConfigError: 配置文件读取或解析失败
        """
        if not os.path.exists(file_path):
            raise PluginConfigError(f"Config file not found: {file_path}")
        
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                config_dict = yaml.safe_load(f) or {}
        except yaml.YAMLError as e:
            raise PluginConfigError(f"Failed to parse YAML: {e}")
        except Exception as e:
            raise PluginConfigError(f"Failed to read config file: {e}")
        
        return PluginConfig(config_dict)
    
    @staticmethod
    def load_from_dict(config_dict: Dict[str, Any]) -> PluginConfig:
        """
        从字典加载配置
        
        Args:
            config_dict: 配置字典
            
        Returns:
            PluginConfig对象
        """
        return PluginConfig(config_dict)
    
    @staticmethod
    def discover_plugins(plugin_dir: str) -> List[str]:
        """
        发现插件目录
        
        Args:
            plugin_dir: 插件根目录
            
        Returns:
            包含plugin.yml的目录列表
        """
        plugin_dirs = []
        
        if not os.path.exists(plugin_dir):
            return plugin_dirs
        
        for item in os.listdir(plugin_dir):
            item_path = os.path.join(plugin_dir, item)
            if os.path.isdir(item_path):
                config_path = os.path.join(item_path, 'plugin.yml')
                if os.path.exists(config_path):
                    plugin_dirs.append(item_path)
        
        return plugin_dirs
    
    @staticmethod
    def save_to_file(config: PluginConfig, file_path: str) -> None:
        """
        保存配置到文件
        
        Args:
            config: PluginConfig对象
            file_path: 保存路径
        """
        try:
            with open(file_path, 'w', encoding='utf-8') as f:
                yaml.safe_dump(config.to_dict(), f, allow_unicode=True)
        except Exception as e:
            raise PluginConfigError(f"Failed to save config: {e}")
